package com.hotelvip.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hotelvip.common.annotation.VipUserAnno;
import com.hotelvip.common.exception.ServiceException;
import com.hotelvip.common.pojo.PageObject;
import com.hotelvip.common.utils.BeanHelper;
import com.hotelvip.common.utils.IdcardUtils;
import com.hotelvip.common.utils.NumberUtil;
import com.hotelvip.common.utils.ShiroUtils;
import com.hotelvip.dao.*;
import com.hotelvip.dto.VipUserDTO;
import com.hotelvip.entity.*;
import com.hotelvip.service.LabelService;
import com.hotelvip.service.UserService;
import com.hotelvip.service.VipCardService;
import com.hotelvip.service.VipUserService;
import com.hotelvip.service.batch.UserLabelService;
import com.hotelvip.service.batch.VUserAndVCardService;
import com.hotelvip.service.batch.VipCardItemService;
import com.hotelvip.vo.UserVo;
import com.hotelvip.vo.VipCardVo;
import com.hotelvip.vo.VipInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ypb
 * @Date:2021/1/20
 */
@Slf4j
@Service
public class VipUserServiceImpl extends ServiceImpl<VipUserMapper, VipUser> implements VipUserService {

    @Autowired
    private UserService userService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private VipCardService vipCardService;

    @Autowired
    private VUserAndVCardService vUserAndVCardService;

    @Autowired
    private UserLabelService userLabelService;

    @Autowired
    private LabelService labelService;

    @Autowired
    private VipUserMapper vipUserMapper;

    @Autowired
    private UserTurnVipMapper userTurnVipMapper;

    @Autowired
    private VItemMapper vItemMapper;

    @Autowired
    private VipCardItemService vipCardItemService;


    /**
     * 普通用户升级会员
     * 会员新增vip卡套餐
     *
     * @param vipUserDTO 所购卡的套餐类型
     * @return
     */
    @VipUserAnno(key = "createVip")
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Long saveVipUser(VipUserDTO vipUserDTO) {
        if (vipUserDTO.getVipCardVo() == null) {
            throw new ServiceException("必须选择一个卡套餐");
        }
        //校验用户
        checkUser(vipUserDTO);

        //1.更改user会员状态
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(User::getVStatus, 1).eq(User::getId, vipUserDTO.getUser().getId());
        boolean b = userService.update(updateWrapper);
        if (!b) {
            throw new ServiceException("会员升级失败");
        }
        //设置过期时间
//        Long l = vipUserDTO.getVipCardVo().getVipCard().getUpload().getTime() + vipUserDTO.getVipCardVo().getVipCard().getDueTime();
        VipUser vipUser = BeanHelper.copyProperties(vipUserDTO, VipUser.class);
        BeanHelper.copyProperties(vipUserDTO.getVipCardVo().getVipCard(), VipUser.class);
//        Date endDate = new Date(l);
//        vipUser.setEndDate(endDate);
        vipUser.setStartDate(new Date());
        vipUser.setVipName(vipUserDTO.getVipCardVo().getVipCard().getVipName());
        //添加其他属性
        vipUser.setUserId(vipUserDTO.getUser().getId());
        vipUser.setCreatedUser(ShiroUtils.getUsername());
        vipUser.setUpdatedUser(ShiroUtils.getUsername());
        vipUser.setUrl(vipUserDTO.getImageVo() == null ? "" : vipUserDTO.getImageVo().getUrl());
        vipUser.setStatus(1);
        vipUser.setVipCode(0L);
        vipUser.setCardId(vipUserDTO.getVipCardVo().getVipCard().getId());
        vipUser.setPath(vipUserDTO.getImageVo().getPath());
        //保存vipUser

        boolean b1 = this.saveOrUpdate(vipUser);
        if (!b1) {
            throw new ServiceException("新增套餐会员失败");
        }
        //保存中间表在切面完成返回值是生成的会员卡id非会员卡获取刚刚存入对象的id并返回,提供给切面使用

        //获取List<Label> 并进行修改和保存
        List<Label> labels = vipUserDTO.getLabels();
        labelService.updateLabelById(vipUserDTO.getUser().getId(), labels);
        //TODO 需要获取当前会员卡套餐的id,将消费信息添加到vipCard表中
        //(还没有做,可以在切面中完成,切面有会员卡号,业务层中还没有获取到)
        //用来作为用户当前会员卡的消费信息
        if (vipUserDTO.getVipCardVo().getVipCard().getVipType() == 0) {
            return vipUser.getId();
        } else if (vipUserDTO.getVipCardVo().getVipCard().getVipType() == 1) {
            List<VItem> vitems = vItemMapper.getSourceVitem(vipUserDTO.getVipCardVo().getVipCard().getId());
            List<VipCardItem> vipCardItems = BeanHelper.copyWithCollection(vitems, VipCardItem.class);
            vipCardItems.forEach(vipCardItem ->
                    vipCardItem.setVitemId(null)
                            .setId(null)
                            .setVId(vipUser.getId())
            );
            vipCardItemService.saveBatch(vipCardItems);
            return vipUser.getId();
        }
        throw new ServiceException("新增标准会员失败");
    }

    /**
     * 校验过程一般放在controller层,这里暂时放在service层
     */
    private void checkUser(VipUserDTO vipUserDTO) {
        User user = vipUserDTO.getUser();
        //判断用户是否存在
        if (user == null) {
            throw new ServiceException("当前用户不可用,未查询到");
        }
        if (user.getId() == null && user.getId() == 0) {
            throw new ServiceException("当前用户不可用,未查询到");
        }
        //校验
        //证件号码
        String cid = vipUserDTO.getCid();
        log.info("" + vipUserDTO.getIdType());
        log.info("" + !IdcardUtils.validateCard(cid));
        if (vipUserDTO.getIdType() == 1) {
            if (cid == null || cid == "" || !IdcardUtils.validateCard(cid)) {
                throw new ServiceException("(陆)证件号码不合法");
            }
        }
        if (vipUserDTO.getIdType() == 2) {
            if (cid == null || cid == "" || !IdcardUtils.validateHKCard(cid)) {
                throw new ServiceException("(港)证件号码不合法");
            }
        }
        log.info("证件号码验证通过");
        //手机号码
        String phone = vipUserDTO.getPhone();
        if (phone == null || phone == "" || !NumberUtil.isPhone(phone)) {
            throw new ServiceException("手机号码验证错误");
        }
        log.info("电话号码验证通过");
        //姓名
        if (vipUserDTO.getPurchaser() == null || vipUserDTO.getPurchaser() == "") {
            throw new ServiceException("购买人姓名不能为空");
        }
    }

    @Override
    public UserVo findByUserId(Long userId) {
        //校验
        if (userId == null || userId == 0) {
            throw new ServiceException("ID不能为空");
        }
        return new UserVo().setUser(userMapper.selectById(userId)).setLabels(labelService.selectLabelById(userId));

    }

    /**
     * 所有vip用户的查询
     *
     * @param key      搜索关键词(用户姓名)
     * @param page     页码数
     * @param rows     每页大小
     * @param phoneNum 手机号
     * @return 返回Vo对象
     */
    @Override
    public PageObject<UserVo> queryVipUserByPage(String key, Integer page, Integer rows, String phoneNum) {
        //准备封装的查询条件
        //如果关键字不为空
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(key)) {
            wrapper.lambda().like(User::getName, key);
        }
        if (phoneNum != null) {
            wrapper.lambda().like(User::getPhone, phoneNum);
        }

        //1为会员状态
        wrapper.lambda().eq(User::getVStatus, 1);
        //默认排序
        wrapper.lambda().orderByDesc(User::getUpdatedTime);
        // 2. 分页对象
        IPage<User> iPage = new Page<>(page, rows);
        iPage = userService.page(iPage, wrapper);

        List<User> userList = iPage.getRecords();
        if (CollectionUtils.isEmpty(userList)) {
            throw new ServiceException("没有会员用户");
        }
        //3.封装分页结果  PageResult  当前页数据  List<UserVo>
        //3.1 将查询到User集合转为UserVo集合
        List<UserVo> userVos = new ArrayList<>();
        for (User user : userList) {
            //将user对象转成VO对象
            QueryWrapper<UserLabel> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(UserLabel::getUserId, user.getId());
            List<UserLabel> list = userLabelService.list(queryWrapper);
            //从list集合中获取label的集合 通过labelId获取label属性
            //使用Stream获取labels的集合(collect)
            List<Integer> labelIds = list.stream().map(UserLabel::getLabelId).collect(Collectors.toList());
            UserVo userVo = new UserVo();
            //查询label集合
            if (!CollectionUtils.isEmpty(labelIds)) {
                List<Label> labelList = labelService.listByIds(labelIds);
                userVos.add(userVo.setUser(user).setLabels(labelList));
            } else {
                userVos.add(userVo.setUser(user));
            }
            //查询label集合
        }
        userVos.forEach(userVo -> {
            List<VipUser> vipUsers = vipUserMapper.selectList(new QueryWrapper<VipUser>().
                    lambda().
                    eq(VipUser::getUserId, userVo.getUser().getId()));
            userVo.setVipUserList(vipUsers);
        });
        return PageObject.setPageObject(iPage.getTotal(), userVos, Long.valueOf(rows), Long.valueOf(page));
    }

    /**
     * 通过用户id查询用户下的所有的会员卡信息
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public List<VipUser> findVipCardByUserId(Long userId) {
        QueryWrapper<VipUser> vipUserQueryWrapper = new QueryWrapper<>();
        vipUserQueryWrapper.lambda().eq(VipUser::getUserId, userId);
        List<VipUser> vipUsers = vipUserMapper.selectList(vipUserQueryWrapper);
        if (vipUsers.size() == 0) {
            throw new ServiceException("用户没有会员卡");
        }
        return vipUsers;
        //通过中间表查询到用户下的所有会员卡的信息
//        QueryWrapper<VUserAndVCard> wrapper = new QueryWrapper<>();
//        wrapper.lambda().eq(VUserAndVCard::getUserId, userId);
//        List<VUserAndVCard> vUserAndVCardList = vUserAndVCardService.list(wrapper);
//        if (CollectionUtils.isEmpty(vUserAndVCardList)) {
//            //用户没有会员卡
//            throw new ServiceException("用户没有会员卡");
//        }
//        //通过卡号集合查询对应的会员卡集合,返回
//        List<Long> cardList = vUserAndVCardList.stream().map(VUserAndVCard::getVipCode).collect(Collectors.toList());
//        List<VipCard> vipCards = vipCardService.listByIds(cardList);
//        if (CollectionUtils.isEmpty(cardList)) {
//            //没有找到对应的会员卡
//            throw new ServiceException("用户没有会员卡");
//        }
//        List<VipCardDTO> vipCardDTOS = BeanHelper.copyWithCollection(vipCards, VipCardDTO.class);
//        return vipCardDTOS;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void deleteVipUserById(Long userId) {
        //判断用户当前状态
        User user = userService.getById(userId);
        if (user.getVStatus() != 1) {
            throw new ServiceException("此用户当前并非会员");
        }
        //判断当前用户是否绑定会员卡，会员卡是否到期
        List<VipUser> vipUsers = vipUserMapper.selectList(new QueryWrapper<VipUser>().lambda().eq(VipUser::getUserId, userId));
        vipUsers.forEach(vipUser -> {
            if (vipUser.getStatus() == 2 || vipUser.getStatus() == 1) {
                throw new ServiceException("当前会员有未失效的会员卡");
            }
        });
        vipUserMapper.delete(new UpdateWrapper<VipUser>().lambda().eq(VipUser::getUserId, userId));
        userService.update(new UpdateWrapper<User>().lambda().eq(User::getId, userId).set(User::getVStatus, 0));


//        //先判断用户是否已经删除(注销)
//        User user = userService.getById(userId);
//        if (user.getDeleted() == 1) {
//            throw new ServiceException("此用户已删除");
//        }
//        //删除用户做一个假删除操作
//        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
//        wrapper.lambda().eq(User::getId, userId);
//        wrapper.lambda().set(User::getDeleted, 1);
//        boolean b = userService.update(wrapper);
//        if (!b) {
//            //更改失败
//            throw new ServiceException("用户删除失败");
//        }
//        //修改此用户下所有的卡为冻结状态
//        List<VipUser> vipCardDTOs = this.findVipCardByUserId(userId);
//        if (vipCardDTOs.isEmpty()) {
//            throw new ServiceException("此用户没有会员卡");
//        }
//        List<VipCard> vipCards = vipCardDTOs.stream().map(vipCardDTO -> {
//            //TODO 删除的卡其实可新添加一张表 专门用于存放已经过期的会员卡号用户会员卡号的回收利用 目前没有做到废弃卡号的回收 所以先保留废弃的会员卡 可以通过status字段将废弃的卡号筛选出老
//
//            //卡的状态设置为3 表示已经注销/或失效 但并不会删除
//            //并设置更改时间
//            vipCardDTO.setStatus(0).setUpdatedTime(new Date());
//            VipCard vipCard = BeanHelper.copyProperties(vipCardDTO, VipCard.class);
//            return vipCard;
//        }).collect(Collectors.toList());
//
//        boolean b1 = vipCardService.saveBatch(vipCards);
//        if (!b1) {
//            throw new ServiceException("会员注銷失败");
//        }
    }

    @Override
    public List<User> selectName(String key) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (key != null && !key.isEmpty()) {
            //查询关键字除去前后空格
            String trim = key.trim();
            wrapper.lambda().like(User::getName, trim).or().like(User::getPhone, trim);
        }
        wrapper.lambda().select(User::getName, User::getPhone).eq(User::getVStatus, 1);
        List<User> users = userService.list(wrapper);
        if (CollectionUtils.isEmpty(users)) {
            return null;
        }
        return users;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void doUpdateVipStatus(Long id, Integer status) {
        //校验参数
        if (id == null) {
            throw new ServiceException("会员卡id不能为空");
        }
        VipUser vipUser = vipUserMapper.selectById(id);
        if (vipUser == null) {
            throw new ServiceException("当前会员卡可能已经不存在");
        }
        if (status == 2) {
            VipCardVo vipCardVo = vipCardService.selectVipCardById(vipUser.getCardId());
            //激活时候更新会员卡有效时间
            Date ativationDate = new Date();
            Long l = vipCardVo.getVipCard().getDueTime() + ativationDate.getTime();
            Date endDate = new Date(l);
            vipUser.setEndDate(endDate);
            vipUser.setAtivationDate(ativationDate);
            boolean update = update(new UpdateWrapper<VipUser>().
                    lambda().
                    eq(VipUser::getId, id).
                    set(VipUser::getStatus, status).
                    set(VipUser::getEndDate, endDate).
                    set(VipUser::getUpdatedUser, ShiroUtils.getUsername()));
            if (!update) {
                throw new ServiceException("激活会员失败");
            }
        } else if (status == -1) {
            if (vipUser.getStatus() != 2) {
                VipUser tempVipUser = vipUserMapper.selectById(id);
                VipCardVo vipCardVo = vipCardService.selectVipCardById(tempVipUser.getCardId());
                if (vipCardVo.getVipCard().getVipType() == 0) {
                    int i = vipUserMapper.deleteById(id);
                    if (i < 1) {
                        throw new ServiceException("会员卡删除失败,当前套餐卡片可能已经不存在");
                    }

                } else if (vipCardVo.getVipCard().getVipType() == 1) {
                    try {
                        vipUserMapper.deleteById(id);
                        vipCardItemService.deleteByUserId(tempVipUser.getId());
                    } catch (Exception e) {
                        throw new ServiceException("会员卡删除失败,当前标准卡片可能已经不存在");
                    }
                }
                if (tempVipUser.getPath() != null && !tempVipUser.getPath().isEmpty()){
                    File file = new File(tempVipUser.getPath());
                    if (file.exists()){
                        file.delete();
                    }
                }
            } else throw new ServiceException("会员卡删除失败,当前会员卡可能处于激活状态");
        } else if (status == 3) {
            boolean update = update(new UpdateWrapper<VipUser>().lambda().eq(VipUser::getId, id).set(VipUser::getStatus, status));
            if (!update) {
                throw new ServiceException("会员状态修改失败");
            }
        } else {
            throw new ServiceException("修改状态错误，请联系管理员 参数 status:" + status);
        }
    }

    @Override
    @Transactional(readOnly = true)
    public Object getVitem(VipUserDTO vipUserDTO) {
        Long cardId = vipUserDTO.getCardId();
        VipCardVo vipCardVo = vipCardService.selectVipCardById(cardId);
        Integer vipType = vipCardVo.getVipCard().getVipType();
        if (vipUserDTO.getPageNum() != null && vipUserDTO.getPageSize() != null) {
            PageHelper.startPage(vipUserDTO.getPageNum(), vipUserDTO.getPageSize());
            if (vipType != null && vipType == 0) {
                return new PageInfo<>(vItemMapper.getFixedVitem(vipUserDTO.getCardId(), 0));
            }
            return new PageInfo<>(vItemMapper.getVitem(vipUserDTO.getId(), 1));
        } else {
            if (vipType != null && vipType == 0) {
                return vItemMapper.getFixedVitem(vipUserDTO.getCardId(), 0);
            }
            return vItemMapper.getVitem(vipUserDTO.getId(), 1);
        }


    }

    @Override
    @Transactional(readOnly = true)
    public List<VipInfoVo> getVipInfo(String key) {
        List<VipInfoVo> vipInfoVos = vipUserMapper.getVipInfo(key);
        return vipInfoVos;
    }


}
